<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/6/12
 * Time: 16:53
 */

namespace app\common\lib;


use app\exception\IndexException;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;

class MoyinTts
{
    protected $secret;

    protected $appkey;

    protected static $instance;

    public function __construct()
    {

        $this->secret = '6C5FC7EF1A5F71E7119F763A85E25DB1';
        $this->appkey = '9EB279303E8A73F33452740E44B703EC';
    }

    public static function getInstance()
    {
        //        if(is_object(self::$instance)){
//            return self::$instance;
//        }


        return new self();
    }

    /**
     * 文本语音合成
     * @param $text
     * @param array $option
     * @return array
     * @throws \Throwable
     */
    public function textToVoice($text,$option=[])
    {
        $time = time();
        $param = [
            'text'=>$text,
            'timestamp'=>$time,
            'appkey'=>$this->appkey,
            'speaker'=>$option['speaker']??'mercury_yunxi_24k',
            'ignore_limit'=>true,
            'gen_srt'=>true,
            'audio_type'=>$option['audio_type']??'mp3',
            'speed'=>floatval($option['speed']??'1.0'),
            'volume'=>floatval($option['volume']??'1.0'),
        ];
        $param['signature'] = md5($this->appkey.'+'.$this->secret.'+'.$time);
        $header = [
            'Content-Type'=>'application/json'
        ];

        $baseUri = 'https://open.mobvoi.com/';
        try{
            $guzzle = new Client([
                'base_uri' => $baseUri,
                'timeout'  => 60,
                // https请求
                'verify' => false,
            ]);
            $domain = parse_url($baseUri,PHP_URL_HOST);
            $cookie = CookieJar::fromArray([],$domain);
            $data = [
                'headers' => $header,
                'json'    => $param,
                'cookies' => $cookie,
            ];
            $response = $guzzle->post('api/tts/v1', $data);
            $responseHeader = $response->getHeaders();
            $content = $response->getBody()->getContents();
            $contents = @json_decode($content, true);
            if(empty($contents)){
                //file_put_contents(runtime_path('mouyin_tts.mp3'),$response->getBody()->getContents());

                $srtAddessData = [];
                if(!empty($responseHeader['srt_address'][0])){
                    //todo 格式化处理字幕
                    $srtAddess = array_filter(explode("\n",file_get_contents($responseHeader['srt_address'][0])));
                    $srtAddessDatas = array_chunk($srtAddess,3);
                    $srtAddessData = [];
                    foreach($srtAddessDatas as $srtAddessRow){
                        $row = [];
                        $srtArr = explode('-->',$srtAddessRow[1]);

                        //开始时间
                        $startTimeArr = explode(',',trim($srtArr[0]));
                        $startTimeHis = explode(':',$startTimeArr[0]);
                        $row['start'] = round(($startTimeHis[0]*3600)+($startTimeHis[1]*60)+$startTimeHis[2])*1000+$startTimeArr[1];

                        //结束时间
                        $startTimeArr = explode(',',trim($srtArr[1]));
                        $startTimeHis = explode(':',$startTimeArr[0]);
                        $row['end'] = round(($startTimeHis[0]*3600)+($startTimeHis[1]*60)+$startTimeHis[2])*1000+$startTimeArr[1];

                        //字幕文本
                        $row['content'] = $srtAddessRow[2]??0;

                        $srtAddessData[] = $row;
                    }
                }

                return ['srt_address_data'=>$srtAddessData,'content'=>$content];
            }else{
                $code = $contents['errorMessage']['code']??4020;
                $desc = $contents['errorMessage']['desc']??'生成失败';
                throw new IndexException($code,$desc);
            }
        }catch (\Throwable $e){
            throw $e;
        }
    }
}